<?php


namespace Buu\Modules\EventSystem\Controllers;

use App\Library\EventCommon;
use App\Models\Event;
use Encore\Admin\Form;
use Encore\Admin\Grid;

//use Doraemon\tools\Log;
use Encore\Admin\Admin;
use App\Models\SubEvent;
use App\Models\DbInstance;
use Encore\Admin\Layout\Row;
use Illuminate\Http\Request;
use App\Models\EventLatitude;
use App\Models\EventProperty;
use Encore\Admin\Layout\Content;
use App\Models\BasicEventLatitude;
use App\Models\EventPropertySetting;
use Encore\Admin\Controllers\AdminController;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\MessageBag;

class EventController extends AdminController
{
    protected $title = '事件管理';

    public function index(Content $content)
    {
        $content->breadcrumb([
            'text' => $this->title
        ]);
        return parent::index($content);
    }

    protected function grid()
    {
        $grid = new Grid(new Event);
        $grid->paginate(50);
        $grid->disableFilter();
        $grid->disableExport();
        $grid->column('id', 'ID');
        $grid->column('name', '事件名称');
        $grid->column('database', '关联库');
        $grid->column('tables', '关联表')->label()->width(200);
        $grid->column('consumer', '消费者')->label()->width(150)
            ->link(function () {
                if (!empty($this->consumer)) {
                    foreach ($this->consumer as $key => $value) {
                        return '/admin/EventSystem/consumer/' . $key . '/setConfig';
                    }
                }
            });

        $grid->actions(function ($actions) {
            $actions->prepend("<a href='event/{$actions->row->id}/config'><i class='fa fa-cogs'></i> 事件属性设置</a>");
        });
        return $grid;
    }

    protected function form()
    {
        $form = new Form(new Event);
        $form->footer(function (Form\Footer $footer) {
            $footer->disableEditingCheck();
            $footer->disableCreatingCheck();
            $footer->disableViewCheck();
        });
        $form->tools(function (Form\Tools $tools) {
            $tools->disableDelete();
            $tools->disableView();
        });
        $form->text('name', '事件名称')->required();
        $form->select('db_instance_id', '数据库实例')->options(DbInstance::all()->pluck('name', 'id'))
            ->load('database', '/admin/EventSystem/db-instance/getDatabases')->required();
        $form->select('database', '关联数据库')->options(function () {
            if ($this->db_instance_id) {
                return DbInstance::getDatabasesById($this->db_instance_id);
            } else {
                return [];
            }
        })->load('tables', '/admin/EventSystem/db-instance/getTables')->required();
        $form->multipleSelect('tables', '关联表')->options(function () {
            if ($this->db_instance_id) {
                return DbInstance::getTablesById($this->db_instance_id, $this->database);
            } else {
                return [];
            }
        })->required();
        $form->multipleSelect('exclude_columns', '过滤字段')->options(function () {
            if ($this->db_instance_id) {
                return DbInstance::getColumnsById($this->db_instance_id, $this->database,$this->tables[0]);
            } else {
                return [];
            }
        })->help('过滤掉一些不用投入rabbitmq的字段，例如一些text类型的大字段');

        $form->deleting(function (Form $form, $id) {
            $this->eventNotice($id, 'delete');
        });

        $form->saved(function (Form $form) {
            $create = $form->isCreating();
            $this->eventNotice($form->model()->id, $create ? 'insert' : 'update');
        });


        return $form;
    }

    public function config($id, Content $content)
    {
        $event = Event::find($id);
        $this->configScript($id);
        $name = Event::query()->where('id', $id)->value('name');
        return $content
            ->title($this->title() . " - " . $name)
            ->description("{$event->name}   数据库:{$event->database}  关联表:{$event->getRawOriginal('tables')}")
            ->breadcrumb(['text' => '事件列表', 'url' => '/EventSystem/event'], [
                'text' => '属性配置'
            ])
            ->row(function (Row $row) {
                $row->column(12, '数据加载中请稍候');
                $row->class('eventManage');
            });
    }

    private function configScript($id)
    {
        Admin::css('/vendor/js/buu-fe/eventManage.min.css');
        Admin::js('/vendor/js/buu-fe/eventManage.min.js');
        $script = <<<EOF
            eventManage.default({
                        selectRequestUrl: '/admin/EventSystem/event/{$id}/getOptions',
                        pageDataRequestUrl: '/admin/EventSystem/event/{$id}/configData',
                        submitRequestUrl: '/admin/EventSystem/event/{$id}/configSave',
                        rootNodeId: 'eventManage'
                    })
EOF;
        Admin::script($script);
    }


    public function configData($id)
    {
        $event = Event::find($id);
        $format = [];
        foreach ($event->latitude as $latitude) {
            $formatProperty = [];
            foreach ($latitude->property as $property) {
                $fromatPropertySetting = [];
                foreach ($property->setting as $setting) {
                    $fromatPropertySetting[] = [
                        'id' => $setting->id,
                        'column' => $setting->column,
                        'condition' => $setting->condition,
                        'value' => $setting->value
                    ];
                }
                $formatProperty[] = [
                    'id' => $property->id,
                    'name' => $property->name,
                    'setting' => $fromatPropertySetting
                ];
            }
            $format[] = [
                'id' => $latitude->id,
                'basic_event_latitude_id' => $latitude->basic_event_latitude_id,
                'property' => $formatProperty
            ];
        }
        return response()->json($format);
    }

    public function configSave($eventId, Request $request)
    {
        $configData = $request->json()->all();
        $hasIds = [];
        foreach ($configData as $latitudeData) {
            if (isset($latitudeData['id'])) {
                $latitude = EventLatitude::where('id', $latitudeData['id'])->where('event_id', $eventId)->where(
                    'basic_event_latitude_id',
                    $latitudeData['basic_event_latitude_id']
                )->firstOrFail();
            } else {
                $latitude = new EventLatitude();
                $latitude->event_id = $eventId;
                $latitude->basic_event_latitude_id = $latitudeData['basic_event_latitude_id'];
                $latitude->save();
            }
            $hasIds['latitude'][] = $latitude->id;
            foreach ($latitudeData['property'] as $propertyData) {
                if (isset($propertyData['id'])) {
                    $property = EventProperty::where('id', $propertyData['id'])->where('event_id', $eventId)->where(
                        'event_latitude_id',
                        $latitude->id
                    )->firstOrFail();
                } else {
                    $property = new EventProperty();
                    $property->event_id = $eventId;
                }
                $property->event_latitude_id = $latitude->id;
                $property->name = $propertyData['name'];
                $property->save();
                $hasIds['property'][] = $property->id;
                foreach ($propertyData['setting'] as $settingData) {
                    if (isset($settingData['id'])) {
                        $propertySetting = EventPropertySetting::where('id', $settingData['id'])->where(
                            'event_id',
                            $eventId
                        )->where('event_property_id', $property->id)->firstOrFail();
                    } else {
                        $propertySetting = new EventPropertySetting();
                        $propertySetting->event_id = $eventId;
                    }
                    $propertySetting->event_property_id = $property->id;
                    $propertySetting->column = $settingData['column'];
                    $propertySetting->condition = $settingData['condition'];
                    $propertySetting->value = $settingData['value'];
                    $propertySetting->save();
                    $hasIds['setting'][] = $propertySetting->id;
                }
            }
        }
        $deleteLatitude = EventLatitude::where('event_id', $eventId)->whereNotIn(
            'id',
            $hasIds['latitude'] ?: []
        )->pluck('id');
        if ($deleteLatitude) {
            EventLatitude::destroy($deleteLatitude);
        }
        $deleteProperty = EventProperty::where('event_id', $eventId)->whereNotIn(
            'id',
            $hasIds['property'] ?: []
        )->pluck('id');
        if ($deleteProperty) {
            EventProperty::destroy($deleteProperty);
        }
        $deleteSetting = EventPropertySetting::where('event_id', $eventId)->whereNotIn(
            'id',
            $hasIds['setting'] ?: []
        )->pluck('id');
        if ($deleteSetting) {
            EventPropertySetting::destroy($deleteSetting);
        }
        Log::debug('configsave', [$configData, $hasIds, $deleteLatitude, $deleteProperty, $deleteSetting]);
        return response()->json([
            'code' => true,
            'message' => '保存成功'
        ]);
    }

    public function getOptions($id)
    {
        $format['latitude'] = BasicEventLatitude::all()->pluck('name', 'id');
        $event = Event::find($id);
        $format['column'] = DbInstance::getTableColumns($event->db_instance_id, $event->database, $event->tables[0]);
        $format['condition'] = EventPropertySetting::ENUM_CONDITION;
        return response()->json($format);
    }

    /**
     * @param $id
     * @param $type string 类型 update delete insert
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function eventNotice($id, string $type)
    {
        $consumerId = SubEvent::query()->where('event_id', $id)->value('consumer_id');
        if ($consumerId) {
            $base = EventCommon::getBaseUrl($consumerId);
            $url = $base . config("event.event_url");
            $data = ['event_id' => $id, 'type' => $type];

            EventCommon::apiNotice($url, $data, __FUNCTION__);
        }
    }
}